package com.cf.auth.granter;

import com.cf.common.constant.RedisConstant;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 验证码模式解析，参考ResourceOwnerPasswordTokenGranter
 * @author ChenFeng
 * @date 2021/11/29 2:53 下午
 * @description
 */
public class CaptchaGranter extends ResourceOwnerPasswordTokenGranter {

    public static final String GRANT_TYPE = "captcha";

    private RedisTemplate redisTemplate;

    public CaptchaGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
        super(authenticationManager, tokenServices, clientDetailsService, requestFactory, grantType);
    }

    public CaptchaGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, RedisTemplate redisTemplate) {
        this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
        this.redisTemplate = redisTemplate;
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        String captchaKey = request.getHeader("Captcha-Key");
        String captchaCode = request.getHeader("Captcha-Code");
        Object code = redisTemplate.opsForValue().get(RedisConstant.CAPTCHA_KEY + captchaKey);
        if (code == null || !String.valueOf(code).equals(captchaCode)) {
            throw new UserDeniedAuthorizationException("验证码不正确");
        }
        OAuth2Authentication oAuth2Authentication = super.getOAuth2Authentication(client, tokenRequest);
        return oAuth2Authentication;
    }
}
